
<!-- tech_news_aggregator/frontend/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>科技新闻聚合器</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.loli.net/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Inter', sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        .news-card {
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            transition: all 0.3s ease;
        }
        .news-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
        }
        .dark-mode {
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
        }
        .dark-mode .news-card {
            background: rgba(26, 32, 44, 0.9);
            color: #e2e8f0;
        }
        .highlight {
            background-color: #fef08a;
            padding: 0 2px;
            border-radius: 2px;
        }
        #particles-js {
            position: fixed;
            width: 100%;
            height: 100%;
            z-index: -1;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body class="bg-gray-50">
    <div id="particles-js"></div>
    <div class="container mx-auto px-4 py-8">
        <header class="mb-8 text-center">
            <h1 class="text-4xl font-bold text-gray-800 mb-2 dark:text-white">科技新闻聚合器</h1>
            <p class="text-gray-600 dark:text-gray-300">每日精选全球科技资讯</p>
            <div class="flex justify-center items-center mt-4 space-x-4">
                <button id="darkModeToggle" class="px-4 py-2 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-white">
                    🌙 暗黑模式
                </button>
                <div class="text-sm text-gray-500 dark:text-gray-400">
                    最后更新: <span id="lastUpdate">正在加载...</span>
                </div>
            </div>
        </header>

        <div class="mb-8 bg-white dark:bg-gray-800 rounded-xl shadow-md p-4">
            <div class="flex flex-wrap justify-between items-center">
                <div class="flex space-x-2 mb-4 md:mb-0">
                    <button onclick="filterNews('all')" class="filter-btn active px-4 py-2 rounded-full bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300">
                        全部
                    </button>
                    <button onclick="filterNews('人工智能')" class="filter-btn px-4 py-2 rounded-full bg-purple-100 dark:bg-purple-900 text-purple-600 dark:text-purple-300">
                        人工智能
                    </button>
                    <button onclick="filterNews('区块链')" class="filter-btn px-4 py-2 rounded-full bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-300">
                        区块链
                    </button>
                    <button onclick="filterNews('生物科技')" class="filter-btn px-4 py-2 rounded-full bg-red-100 dark:bg-red-900 text-red-600 dark:text-red-300">
                        生物科技
                    </button>
                </div>
                <div class="relative w-full md:w-auto">
                    <input type="text" id="searchInput" placeholder="搜索新闻..." class="w-full px-4 py-2 rounded-full border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500">
                    <button onclick="searchNews()" class="absolute right-3 top-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                        🔍
                    </button>
                </div>
            </div>
        </div>

        <div id="loading" class="text-center py-12">
            <div class="inline-block animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
            <p class="mt-2 text-gray-600 dark:text-gray-300">正在加载新闻...</p>
        </div>

        <main id="newsContainer" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 hidden">
            <!-- 新闻卡片将通过JS动态生成 -->
        </main>

        <div id="noResults" class="text-center py-12 hidden">
            <p class="text-gray-600 dark:text-gray-300">没有找到匹配的新闻</p>
        </div>

        <footer class="mt-12 text-center text-gray-500 dark:text-gray-400 text-sm">
            <p>数据每6小时自动更新一次 | © 2025 科技新闻聚合器</p>
            <div class="flex justify-center space-x-4 mt-2">
                <button onclick="shareOnWeibo()" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-200">分享到微博</button>
                <button onclick="shareOnTwitter()" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-200">分享到Twitter</button>
            </div>
        </footer>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/particles.js@2.0.0/particles.min.js"></script>
    <script>
        // 粒子效果初始化
        document.addEventListener('DOMContentLoaded', function() {
            particlesJS('particles-js', {
                particles: {
                    number: { value: 80, density: { enable: true, value_area: 800 } },
                    color: { value: "#3B82F6" },
                    shape: { type: "circle" },
                    opacity: { value: 0.5, random: true },
                    size: { value: 3, random: true },
                    line_linked: { enable: true, distance: 150, color: "#3B82F6", opacity: 0.4, width: 1 },
                    move: { enable: true, speed: 2, direction: "none", random: true, straight: false, out_mode: "out" }
                },
                interactivity: {
                    detect_on: "canvas",
                    events: {
                        onhover: { enable: true, mode: "repulse" },
                        onclick: { enable: true, mode: "push" }
                    }
                }
            });

            // 暗黑模式切换
            const darkModeToggle = document.getElementById('darkModeToggle');
            darkModeToggle.addEventListener('click', function() {
                document.body.classList.toggle('dark-mode');
                const isDark = document.body.classList.contains('dark-mode');
                localStorage.setItem('darkMode', isDark);
                darkModeToggle.innerHTML = isDark ? '☀️ 明亮模式' : '🌙 暗黑模式';
            });

            // 检查本地存储的暗黑模式设置
            if (localStorage.getItem('darkMode') === 'true') {
                document.body.classList.add('dark-mode');
                darkModeToggle.innerHTML = '☀️ 明亮模式';
            }

            // 加载新闻数据
            loadNews();
        });

        // 新闻数据
        let allNews = [];
        let currentFilter = 'all';
        let currentSearch = '';

        // 从本地存储加载新闻数据
        function loadNews() {
            const cachedNews = localStorage.getItem('cachedNews');
            const lastUpdated = localStorage.getItem('lastUpdated');
            
            if (cachedNews && lastUpdated && (Date.now() - parseInt(lastUpdated)) < 6 * 60 * 60 * 1000) {
                // 使用缓存数据
                allNews = JSON.parse(cachedNews);
                updateLastUpdateTime(parseInt(lastUpdated));
                renderNews();
            } else {
                // 从API获取新数据
                fetchNews();
            }
        }

        // 从API获取新闻数据
        async function fetchNews() {
            try {
                // 这里应该是实际的API端点
                const response = await fetch('js/news-loader.js');
                const data = await response.json();
                
                allNews = data.news || [];
                localStorage.setItem('cachedNews', JSON.stringify(allNews));
                localStorage.setItem('lastUpdated', Date.now().toString());
                
                updateLastUpdateTime(Date.now());
                renderNews();
            } catch (error) {
                console.error('获取新闻失败:', error);
                document.getElementById('loading').innerHTML = `
                    <p class="text-red-500">加载新闻失败，请刷新重试</p>
                    <button onclick="fetchNews()" class="mt-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
                        重试
                    </button>
                `;
            }
        }

        // 更新最后更新时间显示
        function updateLastUpdateTime(timestamp) {
            const date = new Date(timestamp);
            const formattedDate = `${date.getFullYear()}-${padZero(date.getMonth()+1)}-${padZero(date.getDate())} ${padZero(date.getHours())}:${padZero(date.getMinutes())}`;
            document.getElementById('lastUpdate').textContent = formattedDate;
        }

        // 补零函数
        function padZero(num) {
            return num < 10 ? `0${num}` : num;
        }

        // 渲染新闻列表
        function renderNews() {
            const container = document.getElementById('newsContainer');
            const loading = document.getElementById('loading');
            const noResults = document.getElementById('noResults');
            
            loading.classList.add('hidden');
            
            // 过滤新闻
            let filteredNews = allNews;
            
            if (currentFilter !== 'all') {
                filteredNews = filteredNews.filter(news => news.category === currentFilter);
            }
            
            if (currentSearch) {
                const searchTerm = currentSearch.toLowerCase();
                filteredNews = filteredNews.filter(news => 
                    news.title.toLowerCase().includes(searchTerm) || 
                    (news.summary && news.summary.toLowerCase().includes(searchTerm)) ||
                    (news.keywords && news.keywords.toLowerCase().includes(searchTerm))
                );
                
                // 高亮搜索关键词
                filteredNews = filteredNews.map(news => {
                    const highlightedTitle = highlightText(news.title, currentSearch);
                    const highlightedSummary = news.summary ? highlightText(news.summary, currentSearch) : '';
                    return { ...news, highlightedTitle, highlightedSummary };
                });
            }
            
            // 清空容器
            container.innerHTML = '';
            
            if (filteredNews.length === 0) {
                noResults.classList.remove('hidden');
                container.classList.add('hidden');
                return;
            }
            
            noResults.classList.add('hidden');
            container.classList.remove('hidden');
            
            // 添加新闻卡片
            filteredNews.forEach(news => {
                const newsCard = document.createElement('div');
                newsCard.className = 'news-card rounded-xl overflow-hidden shadow-md hover:shadow-lg';
                newsCard.innerHTML = `
                    <div class="p-6">
                        <div class="flex justify-between items-start mb-2">
                            <span class="text-xs px-2 py-1 rounded-full ${getCategoryColor(news.category)}">
                                ${news.category}
                            </span>
                            <span class="text-xs text-gray-500 dark:text-gray-400">
                                ${formatTime(news.publish_time)}
                            </span>
                        </div>
                        <h3 class="text-xl font-semibold mb-2 text-gray-800 dark:text-white">
                            <a href="${news.url}" target="_blank" class="hover:text-blue-500 dark:hover:text-blue-400">
                                ${news.highlightedTitle || news.title}
                            </a>
                        </h3>
                        <p class="text-gray-600 dark:text-gray-300 mb-3">
                            ${news.highlightedSummary || (news.summary || '暂无摘要')}
                        </p>
                        <div class="flex justify-between items-center">
                            <span class="text-sm text-gray-500 dark:text-gray-400">
                                ${news.source}
                            </span>
                            <button onclick="shareNews('${encodeURIComponent(news.title)}', '${encodeURIComponent(news.url)}')" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                                ↗️ 分享
                            </button>
                        </div>
                    </div>
                `;
                container.appendChild(newsCard);
            });
        }

        // 文本高亮
        function highlightText(text, searchTerm) {
            if (!searchTerm) return text;
            const regex = new RegExp(searchTerm, 'gi');
            return text.replace(regex, match => `<span class="highlight">${match}</span>`);
        }

        // 获取分类颜色
        function getCategoryColor(category) {
            const colors = {
                '人工智能': 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300',
                '区块链': 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300',
                '生物科技': 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300',
                '硬件': 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300',
                '互联网': 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300',
                '其他': 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300'
            };
            return colors[category] || colors['其他'];
        }

        // 格式化时间
        function formatTime(timeString) {
            if (!timeString) return '';
            const date = new Date(timeString);
            return isNaN(date.getTime()) ? timeString : `${padZero(date.getHours())}:${padZero(date.getMinutes())}`;
        }

        // 过滤新闻
        function filterNews(category) {
            currentFilter = category;
            currentSearch = '';
            document.getElementById('searchInput').value = '';
            
            // 更新活动按钮状态
            document.querySelectorAll('.filter-btn').forEach(btn => {
                btn.classList.remove('active');
                if (btn.textContent.trim() === category || (category === 'all' && btn.textContent.trim() === '全部')) {
                    btn.classList.add('active');
                }
            });
            
            renderNews();
        }

        // 搜索新闻
        function searchNews() {
            const searchInput = document.getElementById('searchInput');
            currentSearch = searchInput.value.trim();
            renderNews();
        }

        // 分享功能
        function shareNews(title, url) {
            if (navigator.share) {
                navigator.share({
                    title: title,
                    text: '看看这篇科技新闻:',
                    url: url
                }).catch(err => {
                    console.log('分享失败:', err);
                });
            } else {
                // 备用分享方式
                const shareUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(url)}`;
                window.open(shareUrl, '_blank');
            }
        }

        function shareOnWeibo() {
            const url = encodeURIComponent(window.location.href);
            const title = encodeURIComponent('科技新闻聚合器 - 每日精选全球科技资讯');
            window.open(`http://service.weibo.com/share/share.php?url=${url}&title=${title}`, '_blank');
        }

        function shareOnTwitter() {
            const url = encodeURIComponent(window.location.href);
            const text = encodeURIComponent('Check out this Tech News Aggregator - Daily curated tech news from around the world');
            window.open(`https://twitter.com/intent/tweet?url=${url}&text=${text}`, '_blank');
        }

        // 监听搜索输入框回车事件
        document.getElementById('searchInput').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                searchNews();
            }
        });
    </script>
</body>
</html>
